import vlc
import tkinter as tk
from tkinter import ttk, filedialog, messagebox
import os
import sys
import random
from urllib.parse import unquote

# 初始化主窗口（带兽兽主题）
root = tk.Tk()
root.title("兽兽放映室 🐾")
root.geometry("800x600")

# 创建VLC实例（取消嵌入式播放）
instance = vlc.Instance("--no-xlib --avcodec-hw=any")
player = instance.media_player_new()

# 全局变量
is_playing = False
is_updating = False
last_error = None
playlist = []
current_playlist_index = -1
playlist_box = None
background_image_path = None
background_label = None

# 播放模式设置
current_play_mode = "sequential"
mode_mapping = {
    "顺序播放": "sequential",
    "单曲循环": "single_loop",
    "随机播放": "random",
    "列表循环": "loop_playlist"
}
reverse_mode_mapping = {v: k for k, v in mode_mapping.items()}
# ========== 新增代码：设置窗口图标 ==========
try:    
# 尝试加载图标文件（可以是.ico或.png）    
    icon_path = "assets/icon.png"  # 替换为你的图标文件路径    
    if os.path.exists(icon_path):        
        root.iconbitmap(icon_path)    
    else:        
        # 如果没有找到图标文件，使用默认图标        
        root.iconbitmap(default=None)
except Exception as e:    
    print(f"[警告] 加载图标失败: {e}")
# 萌化错误提示
def show_error_window(error_message):
    error_window = tk.Toplevel(root)
    error_window.title("呜咪~爪爪按错地方了！(>﹏<)")
    error_window.geometry("500x300")
    
    error_frame = tk.Frame(error_window, bg="#E3F2FD")
    error_frame.pack(fill=tk.BOTH, expand=True)
    
    error_label = tk.Label(
        error_frame, 
        text="❌ 发生错误啦！\n" + error_message,
        font=("Arial", 12), 
        bg="#ffebee",
        fg="#d32f2f",
        justify=tk.CENTER
    )
    error_label.configure(bg="#E3F2FD", fg="#0D47A1")
    error_label.pack(pady=20)
    
    ok_button = tk.Button(
        error_frame, 
        text="好的喵~", 
        command=error_window.destroy,
        bg="#d32f2f",
        fg="white",
        font=("Arial", 10, "bold")
    )
    ok_button.configure(bg="#1976D2", fg="white")
    ok_button.pack(pady=10)

# 播放控制函数
def play_video():
    global is_playing
    try:
        if not player.get_media():
            show_error_window("请先选择要播放的毛茸茸文件呀~")
            return
        
        if player.play() == -1:
            show_error_window("播放器小兽睡着啦，叫不醒...")
            return
        
        is_playing = True
        check_play_status()
    except Exception as e:
        show_error_window(f"播放失败喵：{str(e)}")

def pause_video():
    global is_playing
    try:
        player.pause()
        is_playing = not is_playing
    except Exception as e:
        show_error_window(f"暂停失败喵：{str(e)}")

def stop_video():
    global is_playing
    try:
        player.stop()
        is_playing = False
        progress_var.set(0)
        time_label.config(text="🕒 时间: 00:00 / 00:00")
    except Exception as e:
        show_error_window(f"停止失败喵：{str(e)}")

# 播放列表功能
def add_media_files():
    files = filedialog.askopenfilenames(
        title="选择毛茸茸的媒体文件",
        filetypes=[
            ("兽兽视频", "*.mp4 *.avi *.mkv *.mov *.wmv *.flv *.webm *.m4v"),
            ("兽兽音频", "*.mp3 *.wav *.flac *.aac *.ogg *.wma"),
            ("所有爪爪文件", "*.*")
        ]
    )
    for f in files:
        f = f.replace("/", "\\")
        if f not in playlist:
            playlist.append(f)
            playlist_box.insert(tk.END, os.path.basename(f))
    show_status("添加了 {} 个毛茸茸文件~".format(len(files)))

def add_folder():
    folder = filedialog.askdirectory(title="选择包含毛茸茸文件的文件夹")
    if not folder:
        return
    
    folder = folder.replace("/", "\\")
    supported_ext = {'.mp4', '.avi', '.mkv', '.mov', '.wmv', '.flv', '.webm', '.m4v',
                     '.mp3', '.wav', '.flac', '.aac', '.ogg', '.wma'}
    added = 0
    
    for root_dir, _, files in os.walk(folder):
        for file in files:
            ext = os.path.splitext(file)[1].lower()
            if ext in supported_ext:
                full_path = os.path.join(root_dir, file).replace("/", "\\")
                if full_path not in playlist:
                    playlist.append(full_path)
                    playlist_box.insert(tk.END, file)
                    added += 1
    
    show_status("从文件夹添加了 {} 个毛茸茸文件~".format(added))

def remove_selected():
    try:
        global current_playlist_index
        sel = playlist_box.curselection()
        if not sel:
            show_error_window("请先选择要删除的毛茸茸文件呀~")
            return
        
        idx = sel[0]
        playlist_box.delete(idx)
        removed_path = playlist.pop(idx)
        
        if idx == current_playlist_index:
            stop_video()
            current_playlist_index = -1
        elif idx < current_playlist_index:
            current_playlist_index -= 1
        
        show_status("删除了一条毛茸茸记录~")
    except Exception as e:
        show_error_window(f"删除失败喵：{str(e)}")

def clear_playlist():
    playlist.clear()
    playlist_box.delete(0, tk.END)
    stop_video()
    current_playlist_index = -1
    show_status("清空了所有毛茸茸记录~")

def play_selected():
    try:
        sel = playlist_box.curselection()
        if not sel:
            show_error_window("请先选择要播放的毛茸茸文件呀~")
            return
        
        idx = sel[0]
        path = playlist[idx]
        load_and_play_media(path)
        current_playlist_index = idx
        
        playlist_box.selection_clear(0, tk.END)
        playlist_box.selection_set(idx)
        playlist_box.see(idx)
    except Exception as e:
        show_error_window(f"播放失败喵：{str(e)}")

def load_and_play_media(path):
    global is_playing
    try:
        if not os.path.exists(path):
            show_error_window("找不到这个毛茸茸文件啦！")
            return
        
        path = path.replace("/", "\\")
        media = instance.media_new_path(path)
        player.set_media(media)
        player.audio_set_volume(volume_var.get())
        stop_video()
        play_video()
    except Exception as e:
        show_error_window(f"加载失败喵：{str(e)}")

# 播放模式功能
def get_next_playlist_index():
    global current_playlist_index
    if not playlist:
        return -1
    
    n = len(playlist)
    mode = current_play_mode

    if mode == "sequential":
        next_idx = current_playlist_index + 1
        return next_idx if next_idx < n else -1
    elif mode == "single_loop":
        return current_playlist_index
    elif mode == "random":
        return random.randint(0, n - 1)
    elif mode == "loop_playlist":
        next_idx = current_playlist_index + 1
        return next_idx if next_idx < n else 0
    return -1

def on_play_mode_changed(event):
    global current_play_mode
    selected = play_mode_var.get()
    current_play_mode = mode_mapping[selected]
    show_status("切换到了 {} 模式~".format(selected))

# 背景图功能
def choose_background():
    global background_image_path
    path = filedialog.askopenfilename(
        title="选择可爱的背景图片",
        filetypes=[("图片文件", "*.jpg *.jpeg *.png *.bmp"), ("所有文件", "*.*")]
    )
    if path:
        path = path.replace("/", "\\")
        background_image_path = path
        try:
            img = tk.PhotoImage(file=path)
            if background_label:
                background_label.configure(image=img, text="")
                background_label.image = img
            show_status("更换了可爱的背景图~")
        except Exception as e:
            if background_label:
                background_label.configure(image="", text="背景图加载失败喵~")
                background_label.image = None

# 进度条和时间显示
def update_progress():
    global is_updating
    try:
        if player.get_media() and is_playing:
            is_updating = True
            current_time = player.get_time()
            total_time = player.get_length()
            
            if total_time > 0:
                progress = (current_time / total_time) * 100
                progress_var.set(progress)
                current_str = format_time(current_time)
                total_str = format_time(total_time)
                time_label.config(text="🕒 时间: {} / {}".format(current_str, total_str))
            
            is_updating = False
    except Exception as e:
        show_error_window(f"更新进度失败喵：{str(e)}")
    
    root.after(100, update_progress)

def format_time(milliseconds):
    if milliseconds < 0:
        return "00:00"
    seconds = milliseconds // 1000
    minutes = seconds // 60
    seconds = seconds % 60
    return f"{minutes:02d}:{seconds:02d}"

def on_progress_change(value):
    if not is_updating and player.get_media():
        total_time = player.get_length()
        if total_time > 0:
            target_time = int(float(value) / 100 * total_time)
            player.set_time(target_time)

def on_volume_change(value):
    volume = int(float(value))
    player.audio_set_volume(volume)

# 状态检测
def check_play_status():
    global current_playlist_index
    if is_playing:
        state = player.get_state()
        if state == vlc.State.Error or state == vlc.State.Ended:
            next_idx = get_next_playlist_index()
            if next_idx != -1:
                load_and_play_media(playlist[next_idx])
                current_playlist_index = next_idx
                if playlist_box:
                    playlist_box.selection_clear(0, tk.END)
                    playlist_box.selection_set(next_idx)
                    playlist_box.see(next_idx)
            else:
                stop_video()
                current_playlist_index = -1
                show_status("毛茸茸列表播放完啦~")
    
    root.after(1000, check_play_status)

def show_status(message):
    status_label.config(text="状态: " + message)

# UI布局
# 状态栏
status_frame = ttk.Frame(root)
status_frame.pack(fill=tk.X, padx=5, pady=2)

status_label = ttk.Label(status_frame, text="状态: 等待毛茸茸操作~")
# 状态栏
status_label.configure(foreground="#0D47A1")
status_label.pack(side=tk.LEFT)

# 控制面板
control_frame = ttk.Frame(root)
control_frame.pack(fill=tk.X, padx=5, pady=5)

# 进度条
progress_frame = ttk.Frame(control_frame)
progress_frame.pack(fill=tk.X, pady=2)

time_label = ttk.Label(progress_frame, text="🕒 时间: 00:00 / 00:00")
time_label.pack(side=tk.LEFT)

progress_var = tk.DoubleVar()
progress_bar = tk.Scale(
    progress_frame, from_=0, to=100, orient=tk.HORIZONTAL,
    variable=progress_var, command=on_progress_change
)
# 进度条
progress_bar.configure(    
background='#E1F5FE', troughcolor='#4FC3F7',    
activebackground='#0288D1', foreground="#01579B",    
highlightbackground="#01579B"
)
progress_bar.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=5)

# 音量控制
volume_frame = ttk.Frame(control_frame)
volume_frame.pack(fill=tk.X, pady=2)

volume_label = ttk.Label(volume_frame, text="🔊 音量:")
volume_label.pack(side=tk.LEFT)

volume_var = tk.IntVar(value=100)
volume_scale = tk.Scale(
    volume_frame, from_=0, to=100, orient=tk.HORIZONTAL,
    variable=volume_var, command=on_volume_change
)
# 音量控制
volume_scale.configure(    
background='#E1F5FE', troughcolor='#4FC3F7',    
activebackground='#0288D1', foreground="#01579B",    
highlightbackground="#01579B"
)
volume_scale.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=5)

# 按钮面板
button_frame = ttk.Frame(root)
button_frame.pack(fill=tk.X, padx=5, pady=5)

# 基础按钮
play_button = ttk.Button(button_frame, text="▶️ 播放", command=play_video)
play_button.pack(side=tk.LEFT, padx=2)

pause_button = ttk.Button(button_frame, text="⏸️ 暂停", command=pause_video)
pause_button.pack(side=tk.LEFT, padx=2)

stop_button = ttk.Button(button_frame, text="⏹️ 停止", command=stop_video)
stop_button.pack(side=tk.LEFT, padx=2)

file_button = ttk.Button(button_frame, text="📂 选择文件", command=add_media_files)
file_button.pack(side=tk.LEFT, padx=2)

# 播放列表区域
playlist_frame = ttk.LabelFrame(root, text="📋 毛茸茸播放列表", padding=10)
playlist_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=(5, 10))

list_frame = ttk.Frame(playlist_frame)
list_frame.pack(fill=tk.BOTH, expand=True)

playlist_scroll = ttk.Scrollbar(list_frame)
playlist_scroll.pack(side=tk.RIGHT, fill=tk.Y)

playlist_box = tk.Listbox(
    list_frame, 
    yscrollcommand=playlist_scroll.set,
    selectmode=tk.SINGLE,
    font=("Arial", 10),
    bg="#FFF0F5",
    fg="#FF1493"
)
# 播放列表
playlist_box.configure(    
bg="#E1F5FE",    
fg="#01579B"
)
playlist_box.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
playlist_scroll.config(command=playlist_box.yview)

playlist_btn_frame = ttk.Frame(playlist_frame)
playlist_btn_frame.pack(fill=tk.X, pady=(10, 0))

# 播放列表按钮
ttk.Button(playlist_btn_frame, text="➕ 添加文件", command=add_media_files).pack(side=tk.LEFT, padx=2)
ttk.Button(playlist_btn_frame, text="📁 添加文件夹", command=add_folder).pack(side=tk.LEFT, padx=2)
ttk.Button(playlist_btn_frame, text="🗑️ 删除选中", command=remove_selected).pack(side=tk.LEFT, padx=2)
ttk.Button(playlist_btn_frame, text="🧹 清空列表", command=clear_playlist).pack(side=tk.LEFT, padx=2)
ttk.Button(playlist_btn_frame, text="▶️ 播放选中", command=play_selected).pack(side=tk.LEFT, padx=2)

# 播放模式选择
mode_label = ttk.Label(playlist_btn_frame, text="🎭 播放模式:")
mode_label.pack(side=tk.LEFT, padx=(10, 2))

play_mode_var = tk.StringVar(value="顺序播放")
play_mode_combo = ttk.Combobox(
    playlist_btn_frame, textvariable=play_mode_var,
    values=list(mode_mapping.keys()),
    state="readonly", width=12
)
play_mode_combo.pack(side=tk.LEFT, padx=2)
play_mode_combo.bind("<<ComboboxSelected>>", on_play_mode_changed)

# 背景图区域
bg_frame = ttk.LabelFrame(root, text="🖼 毛茸茸背景图", padding=10)
bg_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=(5, 10))

background_label = tk.Label(
    bg_frame, 
    text="🖼 选择一张可爱的背景图吧~",
    font=("Arial", 14), 
    fg="#FF69B4",
    justify=tk.CENTER
)
# 背景图区域文字颜色
background_label.configure(fg="#0D47A1")
background_label.pack(expand=True)

ttk.Button(bg_frame, text="🖼 选择背景图", command=choose_background).pack(pady=5)

# 初始化
def setup_vlc():
    try:
        pth = filedialog.askopenfilename(
            title="选择毛茸茸的媒体文件",
            filetypes=[
                ("兽兽视频", "*.mp4 *.avi *.mkv *.mov *.wmv *.flv *.webm *.m4v"),
                ("兽兽音频", "*.mp3 *.wav *.flac *.aac *.ogg *.wma"),
                ("所有爪爪文件", "*.*")
            ]
        ) if len(sys.argv) < 2 else sys.argv[1]
        
        if not pth:
            show_status("没有选择毛茸茸文件，兽兽先睡啦~")
            return
            
        pth = pth.replace("/", "\\")
        if not os.path.exists(pth):
            show_error_window("找不到这个毛茸茸文件啦！")
            return
        
        media = instance.media_new_path(pth)
        player.set_media(media)
        player.audio_set_volume(volume_var.get())
        update_progress()
    except Exception as e:
        show_error_window(f"初始化失败喵：{str(e)}")
button_style = ttk.Style()
button_style.configure('TButton',     
background='#2196F3',     
foreground='blue',    
font=('Arial', 10, 'bold')
)
# 时间显示
time_label.configure(foreground="#0D47A1")
root.after(100, setup_vlc)
root.mainloop()
